<template>
	<view class="audio-player">
		<view class="slider">
			<slider @change="sliderChange" :value="currentTime" min="0" :max="totalTime || 100" block-size="12" block-color="#00ccc6" activeColor="#00ccc6"/>
		</view>
		<view class="info">
			<span class="current-time">{{formatTimeMMSS(currentTime)}}</span>
			<view class="button-box">
				<!-- 上一首 -->
				<view class="button pre" @click="handleChange('pre')">
					<image src="../../../static/images/next.png"></image>
				</view>
				<!-- 播放/暂停 -->
				<view class="button" @click="handelClickPlayer">
					<image :src="`../../../static/images/${isPlay ? 'pause' : 'play'}.png`"></image>
				</view>
				<!-- 下一首 -->
				<view class="button next" @click="handleChange('next')">
					<image src="../../../static/images/next.png"></image>
				</view>
			</view>
			<span class="total-time">{{total}}</span>
		</view>
		
	</view>
</template>

<script lang="ts" setup>
import { useEventBus, emitEvent } from '@/hooks/useEventBus';
import type { AudioType } from "../../AudioPanel/AudioPanel.vue";
import { PLAYER_TOAST } from "@/constant/constant";
import { formatTimeMMSS, showToast } from "@/utils/util";
import { ref, defineEmits, defineProps, withDefaults, watch, onUnmounted, computed } from 'vue';
import { onHide, onShow, onLoad } from "@dcloudio/uni-app";
import type { Setting } from '@/components/SettingPopup/SettingPopup.vue';
import { DefaultSetting } from '@/constant/constant';

onLoad(() => {
	setting.value = getApp().globalData!.setting;
})

const totalTime = ref(0);
const currentTime = ref(0);

const current = computed(() => {
	return formatTimeMMSS(currentTime.value);
})
const total = computed(() => {
	return formatTimeMMSS(totalTime.value);
})

interface Props {
	src: string
	type: AudioType
}

const props = withDefaults(defineProps<Props>(), {
	src: ""
})

function sliderChange(e: { detail: { value: number; }; }) {
	const val = e.detail.value;
	audioContext.seek(val);
}

const audioContext = uni.createInnerAudioContext();
const isPlay = ref(false);

function onCanPlay() {
	const duration = audioContext.duration;
	console.log("canplay", duration)
	audioContext.play();
}

function onPlay() {
	
	const duration = audioContext.duration;
	console.log("play: ", duration)
	if (duration) {
		totalTime.value = duration;
	} else {
		audioContext.stop();
		audioContext.play();
	}
	
}

function onTimeUpdate() {
	currentTime.value = audioContext.currentTime;
}

export type PlayChangeType = 'pre' | 'next';

const emit = defineEmits<{
	(e: 'playPreOrNext', isOrder: boolean, type: PlayChangeType): void
}>()

function onEnded() {
	currentTime.value = 0;
	isPlay.value = false;
	audioContext.src = "";
	
	const val = setting.value?.playMode;
	if (val === "loop") {
		
	} else if (val === "order") {
		emit("playPreOrNext", true, 'next');
	} else if (val === "random") {
		emit("playPreOrNext", false, 'next');
	}
	audioContext.play();
	isPlay.value = true;
}

audioContext.onCanplay(onCanPlay);
audioContext.onPlay(onPlay);
audioContext.onTimeUpdate(onTimeUpdate);
audioContext.onEnded(onEnded);


watch(() => props.src, (newSrc: string) => {
	//
	audioContext.src = newSrc;
	isPlay.value = true;

	totalTime.value = 0;
	audioContext.play();
})

watch(isPlay, () => {
	if (props.type === "music") {
		app.globalData!.isMusicPlaying = isPlay.value;
	} else if (props.type === "voice") {
		app.globalData!.isVoicePlaying = isPlay.value;
	}
})

const app = getApp();
function handelClickPlayer() {
	if (!audioContext.src) {
		showToast(PLAYER_TOAST[props.type], "none");
		return;
	}
	
	
	isPlay.value = !isPlay.value;
	isPlay.value ? audioContext.play() : audioContext.pause()
	if (app.globalData!.isVoicePlaying) {
		console.log("watch music")
		emitEvent("pauseVoice", null);
	}
	if (app.globalData!.isMusicPlaying) {
		console.log("watch music")
		emitEvent("pauseMusic", null);
	}
	
}

function handleChange(type: PlayChangeType): void {
	const val = setting.value?.playMode;
	if (val === "loop" || val === "order") {
		emit("playPreOrNext", true, type);
	} else if (val === "random") {
		emit("playPreOrNext", false, type);
	}
}

let isHiding = false;
onHide(() => {
	audioContext.pause();
	isHiding = true;
})

onShow(() => {
	if (isHiding && isPlay.value) {
		audioContext.play();
		isHiding = false;
	}

})

onUnmounted(() => {
	audioContext.offPlay(onPlay)
	audioContext.offCanplay(onCanPlay);
	audioContext.offEnded(onEnded);
	audioContext.offTimeUpdate(onTimeUpdate);
	audioContext.destroy();
})

if (props.type === "music") {
	
	useEventBus("pauseMusic", () => {
		console.log("pauseMusic")
		audioContext.pause();
		isPlay.value = false;
		app.globalData!.isMusicPlaying = false;
	})
}

if (props.type === "voice") {
	
	useEventBus("pauseVoice", () => {
		console.log("pauseVoice")
		audioContext.pause()
		isPlay.value = false;
		app.globalData!.isVoicePlaying = false;
	})
}
const setting = ref<Setting>();

useEventBus("changeSetting", (s) => {
	setting.value = s;
})
</script>

<style lang="scss" scoped>
.audio-player {
	margin: 10rpx auto;
	.info {
		// margin-top: 10rpx;
		display: flex;
		justify-content: space-between;
		.current-time {
			flex: 1;
			text-align: left;
		}
		.button-box {
			display: flex;
			flex: 2;
			justify-content: space-between;
			
			
			.button {
				margin: 16rpx auto;
				width: 60rpx;
				height: 60rpx;
				
				image {
					width: 100%;
					height: 100%;
				}
			}
			
			.pre {
				transform: scaleX(-1);
			}
			
		}
		.total-time {
			flex: 1;
			text-align: right;
		}
	}
}
	
	
	
	
</style>